<template>
  <a-drawer
    :title="title"
    :maskClosable="true"
    :visible="visible"
    :destroyOnClose="true"
    :width="800"
    :body-style="{ paddingBottom: '60px' }"
    @close="closeModal"
  >
    <a-form layout="vertical">
      <section v-show="step == 1">
        <div class="text-title">基本信息</div>
        <a-form-item
          label="规则名称"
          class="mt-10"
          v-bind="validateInfos.rule_name"
        >
          <a-input placeholder="请输入" v-model:value="modelRef.rule_name" />
        </a-form-item>
        <a-form-item label="关联楼宇" v-bind="validateInfos.relation_builds">
          <a-alert
            v-if="disabledTree"
            show-icon
            type="warning"
            message="该提醒规则原来绑定的项目/楼宇，您未全部选中，无法修改。"
            class="mb-10"
          />
          <ChooseHousingResources
            checkType="build"
            :allDisabled="disabledTree"
            :defaultChecked="{ buildList: checkedBuildList }"
            @request="$utils.commonRequest"
            @getResult="getResult"
            @error="setCheckedError"
          />
        </a-form-item>
      </section>
      <section v-show="step == 2">
        <div class="text-title">提醒规则</div>
        <a-card
          class="mt-10"
          v-if="modelRef.sreen_condition"
          title="默认条件"
          size="small"
          key="rule_default"
        >
          <a-row :gutter="16" align="bottom">
            <a-col :span="12">
              <a-form-item
                :label="RULE_MAP[ruleType].timeTitle"
                v-bind="validateInfos['sreen_condition.time']"
              >
                <a-input
                  v-model:value="modelRef.sreen_condition.time"
                  placeholder="请输入..."
                />
              </a-form-item>
            </a-col>
            <a-col :span="6">
              <a-form-item label="">
                <a-select v-model:value="modelRef.sreen_condition.unit">
                  <a-select-option
                    v-for="unit of defaultUnitList"
                    :key="unit.key"
                    :value="unit.key"
                  >
                    {{ unit.title }}
                  </a-select-option>
                </a-select>
              </a-form-item>
            </a-col>
          </a-row>
        </a-card>
        <template v-if="screenRuleList.length">
          <a-card
            v-for="(rule, ruleIndex) of screenRuleList"
            :key="rule.id"
            class="mt-10"
            :title="'筛选条件' + (ruleIndex + 1)"
            size="small"
          >
            <template #extra>
              <a-button type="link" danger @click="delRuleItem(ruleIndex)">
                <template #icon><CloseCircleFilled /></template>
              </a-button>
            </template>
            <a-row :gutter="16" align="bottom">
              <a-col :span="6">
                <a-form-item
                  :label="RULE_MAP[ruleType].timeTitle"
                  v-bind="validateInfos[rule.id + '.time']"
                >
                  <a-input
                    v-model:value="rule.time"
                    placeholder="请输入"
                    @change="handleInputChange(rule.id, 'time', rule.time)"
                  />
                </a-form-item>
              </a-col>
              <a-col :span="4">
                <a-form-item label="" v-bind="validateInfos[rule.id + '.unit']">
                  <a-select
                    v-model:value="rule.unit"
                    @select="(val) => handleScreenUnitSelect(val, ruleIndex)"
                  >
                    <a-select-option
                      v-for="unit of screenUnitList"
                      :key="unit.key"
                      :value="unit.key"
                    >
                      {{ unit.title }}
                    </a-select-option>
                  </a-select>
                </a-form-item>
              </a-col>
            </a-row>
            <template v-if="rule.list && rule.list.length">
              <a-row
                :gutter="16"
                align="bottom"
                v-for="(screenItem, screenIndex) of rule.list"
                :key="screenItem.id"
              >
                <a-col :span="6" :offset="screenIndex > 0 ? 1 : 0">
                  <a-form-item
                    :label="screenIndex == 0 ? '筛选项' : 'AND'"
                    v-bind="validateInfos[rule.id + '.' + screenItem.id]"
                  >
                    <a-select
                      v-model:value="screenItem.key"
                      @select="
                        (val) =>
                          handleScreenItemSelect(val, ruleIndex, screenIndex)
                      "
                      placeholder="请选择"
                    >
                      <a-select-option
                        v-for="screen of screenList"
                        :key="screen.key"
                        :value="screen.key"
                      >
                        {{ screen.title }}
                      </a-select-option>
                    </a-select>
                  </a-form-item>
                </a-col>
                <template v-if="screenItem.key">
                  <a-col :span="4">
                    <a-form-item
                      label=""
                      v-bind="
                        validateInfos[
                          rule.id + '.' + screenItem.id + '_relation'
                        ]
                      "
                    >
                      <a-select
                        v-model:value="screenItem.relation"
                        @select="
                          (val) =>
                            handleScreenRelationSelect(
                              val,
                              ruleIndex,
                              screenIndex
                            )
                        "
                        placeholder="请选择"
                      >
                        <a-select-option
                          v-for="relation of relationList"
                          :key="relation.key"
                          :value="relation.key"
                        >
                          {{ relation.title }}
                        </a-select-option>
                      </a-select>
                    </a-form-item>
                  </a-col>
                  <template
                    v-for="(inputValue, inputIndex) of screenItem.value"
                    :key="'input_' + inputIndex"
                  >
                    <a-col :span="1" v-if="inputIndex > 0">
                      <a-form-item label="">
                        <span>~</span>
                      </a-form-item>
                    </a-col>
                    <a-col :span="3">
                      <a-form-item
                        v-bind="
                          validateInfos[
                            rule.id +
                              '.' +
                              screenItem.id +
                              '_value_' +
                              inputIndex
                          ]
                        "
                      >
                        <a-input
                          v-model:value="screenItem.value[inputIndex]"
                          placeholder="请输入"
                          @change="
                            handleInputChange(
                              rule.id,
                              screenItem.id + '_value_' + inputIndex,
                              screenItem.value[inputIndex]
                            )
                          "
                        />
                      </a-form-item>
                    </a-col>
                  </template>
                  <a-col :span="4">
                    <a-form-item
                      label=""
                      v-bind="
                        validateInfos[rule.id + '.' + screenItem.id + '_unit']
                      "
                    >
                      <a-select
                        v-model:value="screenItem.unit"
                        placeholder="请选择"
                        @select="
                          (val) =>
                            handleScreenUnitSelect(val, ruleIndex, screenIndex)
                        "
                      >
                        <a-select-option
                          v-for="unit of screenItem.unitList"
                          :key="unit.key"
                          :value="unit.key"
                        >
                          {{ unit.title }}
                        </a-select-option>
                      </a-select>
                    </a-form-item>
                  </a-col>
                </template>
                <a-col :span="1" v-if="screenIndex > 0">
                  <a-form-item label="">
                    <a-button
                      type="link"
                      danger
                      @click="delScreenItem(ruleIndex, screenIndex)"
                    >
                      <template #icon><CloseCircleFilled /></template>
                    </a-button>
                  </a-form-item>
                </a-col>
              </a-row>
            </template>
            <a-row>
              <a-button
                type="primary"
                ghost
                @click="addScreenRuleItem(ruleIndex)"
              >
                <template #icon>
                  <PlusOutlined />
                </template>
                筛选项
              </a-button>
            </a-row>
          </a-card>
        </template>
        <a-row class="flex flex-end mt-10" v-if="false">
          <a-button @click="addScreen()" type="primary">
            <template #icon>
              <PlusOutlined />
            </template>
            筛选条件
          </a-button>
        </a-row>
      </section>
    </a-form>
    <div class="drawer-footer flex justify-between">
      <a-button type="primary" @click.prevent="nextStep" v-if="step == 1">
        下一步
      </a-button>
      <template v-if="step == 2">
        <a-button @click.prevent="lastStep">上一步</a-button>
        <a-button type="primary" @click.prevent="onSubmit" :loading="submiting"
          >保存</a-button
        >
      </template>
    </div>
  </a-drawer>
</template>

<script>
import { defineComponent, ref, computed, watch, reactive, toRaw } from "vue";
import { Form, message } from "ant-design-vue";
import {
  CaretRightOutlined,
  PlusOutlined,
  CloseCircleFilled,
} from "@ant-design/icons-vue";
import { ChooseHousingResources } from "bl-common-vue3";
import request from "../../../../common/utils/request";
import utils from "../../../../common/utils/utils";

const useForm = Form.useForm;

const RULE_MAP = {
  // 合同到期提醒
  expire: {
    detail: "/contract/expireRuleDetail",
    add: "/contract/addExpriceRule",
    edit: "/contract/editExpriceRule",
    needJson: true,
    timeTitle: "合同到期前提醒时间",
  },
  // 合同分成录入提醒
  divide: {
    detail: "/contract/divideRemindDetail",
    add: "/contract/addDivideRemind",
    edit: "/contract/editDivideRemind",
    needJson: false,
    timeTitle: "分成合同每期租赁账单应收前提醒录入营业额",
  },
};

export default defineComponent({
  name: "expireRuleAdd",
  components: {
    ChooseHousingResources,
    CaretRightOutlined,
    PlusOutlined,
    CloseCircleFilled,
  },
  props: {
    visible: {
      type: Boolean,
      default: false,
    },
    ruleType: {
      type: String,
      default: "expire",
    },
    id: {
      type: [String, Number],
      default: 0,
    },
  },
  setup(props, context) {
    //   标题
    const title = computed(() => {
      return props.id ? "编辑提醒规则" : "添加提醒规则";
    });

    // 步骤
    const step = ref(1);
    // 上一步
    const lastStep = () => {
      step.value--;
    };
    // 下一步
    const nextStep = () => {
      if (!disabledTree.value && checkedBuildList.value.length) {
        modelRef.relation_builds = utils.getProjectBuildByBuildList(
          checkedBuildList.value
        );
      }
      setTimeout(() => {
        validate().then(() => {
          initStep2Data();
          step.value++;
        });
      }, 0);
    };

    /**
     * @description:  step1
     */
    // 楼宇信息
    const disabledTree = ref(false);
    const setCheckedError = (e) => {
      disabledTree.value = true;
    };

    const getResult = (info) => {
      if (disabledTree.value) {
        return;
      }
      const { villageList, buildList } = info;
      let list = [];
      if (villageList.length) {
        for (let village of villageList) {
          list = [...list, ...village.children];
        }
      }
      if (buildList.length) {
        list = [...list, ...buildList];
      }
      checkedBuildList.value = list;
    };

    /**
     * @description:  step2
     */
    // 单位列表
    const defaultUnitList = ref([]);
    const screenList = ref([]);
    const relationList = ref([]);
    const screenUnitList = ref([]);
    // 筛选条件
    const screenRuleList = ref([]);
    // 筛选值
    const screenObj = ref({});
    // 表单验证
    const inputRuleRef = [
      {
        required: true,
        validator: (rules, value) => utils.numberValidator(rules, value),
      },
    ];
    const selectRuleRef = [{ required: true, message: "请选择" }];
    const initStep2Data = () => {
      // 获取单位等配置
      request.get("/org", "/contract/expireRuleInit").then((res) => {
        const defaultData = res.data.default;
        const mainData = res.data.main;
        defaultUnitList.value = defaultData.unit;
        screenList.value = mainData.screen;
        relationList.value = mainData.relation;
        screenUnitList.value = mainData.unit;
        // 提醒规则
        if (props.id) {
          setScreenRuleListBydetail();
        } else {
          modelRef.sreen_condition = {
            time: 90, // 提醒期限
            unit: defaultUnitList.value.length
              ? defaultUnitList.value[0].key
              : undefined, // 单位
          };
        }
        rulesRef["sreen_condition.time"] = inputRuleRef;
        screenObj.value = {
          id: "rule_0",
          key: undefined, // 筛选值
          value: [], // input值
          relation: relationList.value.length
            ? relationList.value[0].key
            : undefined,
        };
      });
    };
    const setScreenRuleListBydetail = () => {
      const { sreen_condition } = detail;
      modelRef.sreen_condition = {
        time: sreen_condition.time,
        unit: sreen_condition.unit,
      };
      screenRuleList.value = [];
      if (sreen_condition.list && sreen_condition.list.length) {
        screenRuleList.value = sreen_condition.list.map((screen) => {
          let screenItem = getScreenItem(screen);
          if (screen.list && screen.list.length) {
            screen.list = screen.list.map((item) => {
              let ruleItem = getScreenRuleItem(item);
              setModelAndRule(
                "select",
                screenItem.id,
                ruleItem.id,
                ruleItem.key
              ); // key
              setModelAndRule(
                "select",
                screenItem.id,
                `${ruleItem.id}_relation`,
                ruleItem.relation
              ); // relation
              setInputModalValue(screenItem.id, ruleItem.id, ruleItem.value); // value
              setModelAndRule(
                "select",
                screenItem.id,
                `${ruleItem.id}_unit`,
                ruleItem.unit
              ); // unit
              return ruleItem;
            });
          }
          setModelAndRule("input", screenItem.id, "time", screenItem.time);
          setModelAndRule("select", screenItem.id, "unit", screenItem.unit);
          return screenItem;
        });
      }
    };
    // 添加筛选条件
    let ruleCount = 0;
    const addScreen = () => {
      const screenItem = getScreenItem();
      screenRuleList.value.push(screenItem);
      setModelAndRule("input", screenItem.id, "time"); // time
      setModelAndRule("select", screenItem.id, "unit", screenItem.unit); // unit
      setModelAndRule("select", screenItem.id, "rule_0");
    };
    const getScreenItem = (item) => {
      ruleCount++;
      const id = "screen_" + ruleCount;
      if (item) {
        return {
          id,
          ...item,
        };
      } else {
        return {
          id,
          time: "", //提醒期限
          unit: screenUnitList.value.length
            ? screenUnitList.value[0].key
            : undefined, // 单位
          list: [{ ...screenObj.value }],
        };
      }
    };
    // 删除筛选条件
    const delRuleItem = (index) => {
      delModalAndRule(screenRuleList.value[index].id);
      screenRuleList.value.splice(index, 1);
    };
    const setModelAndRule = (type, key1, key2, value) => {
      const rule = type == "select" ? selectRuleRef : inputRuleRef;
      const currentModel = modelRef[key1];
      if (currentModel) {
        currentModel[key2] = value;
      } else {
        modelRef[key1] = { [key2]: value };
      }
      rulesRef[`${key1}.${key2}`] = rule;
    };
    const delModalAndRule = (key1, key2) => {
      let currentModel = modelRef[key1];
      if (key2) {
        for (let key in currentModel) {
          if (key.indexOf(key2) > -1) {
            delete currentModel[key];
            delete rulesRef[`${key1}.${key}`];
          }
        }
      } else {
        for (let key in currentModel) {
          delete rulesRef[`${key1}.${key}`];
        }
        delete modelRef[key1];
      }
    };
    // 添加筛选项
    let itemCount = 0;
    const addScreenRuleItem = (index) => {
      const screenRule = screenRuleList.value[index];
      const item = getScreenRuleItem();
      screenRule.list.push(item);
      setModelAndRule("select", screenRule.id, item.id);
    };
    const getScreenRuleItem = (item) => {
      itemCount++;
      const id = "rule_" + itemCount;
      if (item) {
        const selectedKeyItem = screenList.value.find(
          (unitItem) => item.key == unitItem.key
        );
        item.unitList = selectedKeyItem.unit; // unitList
        return { id, ...item };
      } else {
        return { id, ...screenObj.value };
      }
    };
    // 删除选中项
    const delScreenItem = (ruleIndex, screenIndex) => {
      const screenRule = screenRuleList.value[ruleIndex];
      delModalAndRule(screenRule.id, screenRule.list[screenIndex].id);
      screenRule.list.splice(screenIndex, 1);
    };
    // 选中筛选项
    const handleScreenItemSelect = (value, ruleIndex, screenIndex) => {
      const selectedItem = screenList.value.find((item) => item.key == value);
      const currentScreen = screenRuleList.value[ruleIndex].list[screenIndex];
      currentScreen.unit = selectedItem.unit.length
        ? selectedItem.unit[0].key
        : undefined;
      currentScreen.unitList = selectedItem.unit;
      currentScreen.value =
        currentScreen.value && currentScreen.value.length
          ? currentScreen.value
          : [""];
      // 同步到modelRef
      modelRef[screenRuleList.value[ruleIndex].id][currentScreen.id] = value;
      setModelAndRule(
        "select",
        screenRuleList.value[ruleIndex].id,
        `${currentScreen.id}_relation`,
        currentScreen.relation
      );
      setModelAndRule(
        "select",
        screenRuleList.value[ruleIndex].id,
        `${currentScreen.id}_unit`,
        currentScreen.unit
      );
      setInputModalValue(
        screenRuleList.value[ruleIndex].id,
        currentScreen.id,
        currentScreen.value
      );
    };
    // 选中筛选关系
    const handleScreenRelationSelect = (value, ruleIndex, screenIndex) => {
      const currentScreen = screenRuleList.value[ruleIndex].list[screenIndex];
      setModelAndRule(
        "select",
        screenRuleList.value[ruleIndex].id,
        `${currentScreen.id}_relation`,
        value
      );
      if (value == "relation_5") {
        // 介于两者之间，需要两个输入框
        currentScreen.value = ["", ""];
      } else {
        currentScreen.value = [""];
      }
      setInputModalValue(
        screenRuleList.value[ruleIndex].id,
        currentScreen.id,
        currentScreen.value
      );
    };
    const setInputModalValue = (screenId, ruleId, value) => {
      for (let i in value) {
        setModelAndRule("input", screenId, `${ruleId}_value_${i}`, value[i]);
      }
    };

    // 监听合同到期提醒项
    const handleScreenUnitSelect = (value, index, index2) => {
      const screenItem = screenRuleList.value[index];
      if (index2 != undefined) {
        setModelAndRule("select", screenItem.id, "unit", value);
      } else {
        setModelAndRule(
          "select",
          screenItem.id,
          `${screenItem.list[index2]}_unit`,
          value
        );
      }
    };

    // 监听输入框变化，同步到modelRef
    const handleInputChange = (key1, key2, value) => {
      modelRef[key1][key2] = value;
    };

    /**
     * @description:  表单
     */
    const modelRef = reactive({
      rule_name: "",
      relation_builds: null, // 楼宇信息
    });
    const rulesRef = reactive({
      rule_name: [{ required: true, message: "请输入规则名称" }],
      relation_builds: [{ required: true, message: "请勾选关联楼宇" }],
    });

    const { resetFields, validate, validateInfos } = useForm(
      modelRef,
      rulesRef
    );

    const closeModal = () => {
      context.emit("cancel");
    };

    const submiting = ref(false);
    const onSubmit = () => {
      setTimeout(() => {
        validate().then(() => {
          submiting.value = true;
          const list = JSON.parse(JSON.stringify(screenRuleList.value));
          let params = {
            rule_name: modelRef.rule_name,
            sreen_condition: modelRef.sreen_condition,
            relation_builds: modelRef.relation_builds,
            needMsg: true,
          };
          params.sreen_condition.list = list.map((rule) => {
            delete rule.id;
            if (rule.list && rule.list.length) {
              rule.list = rule.list.map((screen) => {
                delete screen.id;
                delete screen.unitList;
                return screen;
              });
            }
            return rule;
          });
          if (RULE_MAP[props.ruleType].needJson) {
            params.relation_builds = JSON.stringify(params.relation_builds);
            params.sreen_condition = JSON.stringify(params.sreen_condition);
          }

          const success = (res) => {
            message.success(res.msg || "保存成功");
            context.emit("success");
          };
          let requestMethod = "post";
          let requestUrl = RULE_MAP[props.ruleType].add;
          if (props.id) {
            params.id = props.id;
            requestMethod = "put";
            requestUrl = RULE_MAP[props.ruleType].edit;
          }
          request[requestMethod]("/org", requestUrl, params)
            .then((res) => success(res))
            .finally(() => {
              submiting.value = false;
            });
        });
      }, 0);
    };
    let detail = {};
    const checkedBuildList = ref([]);
    const getDetail = () => {
      request
        .get("/org", RULE_MAP[props.ruleType].detail, {
          id: props.id,
        })
        .then((res) => {
          detail = res.detail;
          modelRef.rule_name = detail.rule_name;
          modelRef.relation_builds = detail.relation_builds;
          if (detail.relation_builds && detail.relation_builds.buildId) {
            checkedBuildList.value = detail.relation_builds.buildId.map(
              (id) => ({ id })
            );
          }
        });
    };

    // 初始化
    const init = () => {
      if (props.id) {
        getDetail();
      }
    };

    watch(
      () => props.visible,
      (val) => {
        if (val) {
          init();
        } else {
          resetFields();
          step.value = 1;
          screenRuleList.value = [];
          checkedBuildList.value = false;
          disabledTree.value = false;
        }
      }
    );

    return {
      title,
      step,
      defaultUnitList,
      screenUnitList,
      relationList,
      screenList,
      screenRuleList,
      modelRef,
      validateInfos,
      lastStep,
      nextStep,
      closeModal,
      onSubmit,
      addScreen,
      addScreenRuleItem,
      handleScreenItemSelect,
      handleScreenRelationSelect,
      handleInputChange,
      delScreenItem,
      delRuleItem,
      submiting,
      handleScreenUnitSelect,
      checkedBuildList,
      getResult,
      setCheckedError,
      disabledTree,
      RULE_MAP,
    };
  },
});
</script>

<style lang="less" scoped>
@listItemHeight: 40px;
.building-list {
  .list-header {
    display: flex;
    height: @listItemHeight;
    align-items: center;
    .title {
      margin-left: 10px;
    }
  }
  .list {
    margin-top: 10px;
    margin-left: 20px;
    .item {
      height: @listItemHeight;
      display: flex;
      align-items: center;
      .title {
        margin-left: 10px;
        flex: 1;
        padding: 10px;
        border-radius: 4px;
        cursor: pointer;
        &:hover {
          background: #f7f7f7;
        }
      }
    }
  }
}
</style>
